#include "RegularPointer_new_lyvm.h"
#include "xVMRelationStruct.h"
#include "Collision_lyvm.h"

void RegularPointer_new_lyvm::doNewLayout(DIVA_VM *vm) {

	vector<DIVA_VM *> VMs ;
	vector<DIVA_VM *>::iterator itr ;
	addRecord(vm,vm->getPosition());

	VMs = xVMRelationStruct::getInstance()->VMRS_preVMsByRef(vm);
	

	if(VMs.size() == 0){
		return ;
	}
	//assert(VMs.size() == 1);
	Ogre::Vector3 theTranslateVector = Ogre::Vector3(0,0,0);
	Ogre::Vector3 newpos = Ogre::Vector3(0,0,0);
	for (itr = VMs.begin(); itr != VMs.end(); itr++) {
		DIVA_VM *ref = (*itr);
		DIVA_VM *root = xVMRelationStruct::getInstance()->VMRS_toCompositeRootVM(ref);

		// compute the vector from center of the root to the ref VM
		Ogre::Vector3 rootpos = root->getWorldPosition();
		Ogre::Vector3 refpos = ref->getWorldPosition();
		Ogre::Vector3 vec = refpos-rootpos;
		vec.normalise();
		if (Ogre::Math::Abs(vec.x) < 0.0001 &&
			Ogre::Math::Abs(vec.y) < 0.0001 &&
			Ogre::Math::Abs(vec.z) < 0.0001 ) {				

		} else {
			// we want to set the position along the vector
			Ogre::Vector3 rootsize = root->getActualSize();
			Ogre::Vector3 incr = vec * rootsize * 1.5 ;
			newpos = rootpos+incr ;
			theTranslateVector = incr;
			if(vm->isDraggedOn()){
				addRecord(vm,newpos);				
			}
		}

		if(Collision_lyvm::getInstance()->lyvmIsTurnOn()){
			std::vector<DIVA_VM*> cant_move;
			cant_move.push_back(root);
			cant_move.push_back(vm);
			Collision_lyvm::getInstance()->collision_handling(cant_move,vm);
			cant_move.clear();
		}
	}
	vector<DIVA_VM *> childVMs;
	vector<DIVA_VM *>::iterator child_it;
	childVMs = xVMRelationStruct::getInstance()->VMRS_nextVMsByRef(vm);
	if(childVMs.size() == 0){
		return ;
	}
	arrangeChildVM(childVMs,newpos,theTranslateVector);
}

void RegularPointer_new_lyvm::arrangeChildVM(std::vector<DIVA_VM*> vms,Ogre::Vector3 rootPos,Ogre::Vector3 theVector){
	vector<DIVA_VM *>::iterator itr ;
	for (itr = vms.begin(); itr != vms.end(); itr++) {
		DIVA_VM *ref = (*itr);
		DIVA_VM *child = xVMRelationStruct::getInstance()->VMRS_toCompositeRootVM(ref);
		
		Ogre::Vector3 newpos = theVector+rootPos;
		if(child->isDraggedOn()){			
			addRecord(child,newpos);				
		}
								
		
		vector<DIVA_VM*> childs = xVMRelationStruct::getInstance()->VMRS_nextVMsByRef(ref);
		if(childs.size() != 0){
			arrangeChildVM(childs,newpos,theVector);
		}
		else{
			return ;
		}
	}
}

void RegularPointer_new_lyvm::addRecord(DIVA_VM* vm,Ogre::Vector3 pos){
	_record[vm] = pos;	
}

void RegularPointer_new_lyvm::setChange(){
	if(_record.size() == 0){
		return;
	}
	else{
		positionmap::iterator it;
		for(it = _record.begin() ; it != _record.end() ; ++it){
			DIVA_VM* vm = (*it).first;
			Ogre::Vector3 pos = (*it).second;			
			vm->setPosition(pos);			
		}
	}
}